package br.ufrj.cg.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;

import br.ufrj.cg.model.BackgroundLabel;
import br.ufrj.cg.model.StampBackgroundImage;
import br.ufrj.cg.model.StampImage;

public class MainWindow extends JFrame {

	private static final long serialVersionUID = 1L;

	int idImagem = 0;

	private JPanel pnlMainPanel = null;
	private JPanel pnlImagePanel = null;
	private PreviewPanel pnlPreview = null;
	private StampsPanel pnlStampsPanel = null;
	private JScrollPane scrImagePanel = null;
	
	private BackgroundLabel lblBackgroundImageLabel = null;

	private ImageUploaderWindow imageUploader;
	
	private StampImage currentStampImage = null;
	private JMenuBar menuBar = null;
	private JMenu mnFile = null;
	private JMenuItem mntmLoadImage = null;
	private JMenuItem mntmSaveImage = null;
	private JMenuItem mntmExit = null;
	private JMenu mnEdit = null;
	private JMenuItem mntmResetImage = null;
	private JMenuItem mntmExportAsXml = null;

	private JMenu mnImage = null;
	private JMenuItem mntmMirrorHorizontally = null;
	private JMenuItem mntmMirrorVertically = null;
	
	private JMenu mnRotate = null;
	private JMenuItem mntmRotateBy90Clockwise = null;
	private JMenuItem mntmRotateBy90AntiClockwise = null;
	private JMenuItem mntmRotateBy180 = null;
	private JMenuItem mntmRotateBy270 = null;	
	
	private JMenuItem mntmResize = null;
	private JMenu mnEffects = null;
	private JMenuItem mntmInvertColors = null;
	private JMenuItem mntmToSepia = null;
	private JMenuItem mntmToGrayScale = null;
	private JMenuItem mntmColorizeToRed;
	private JMenuItem mntmColorizeToBlue;
	private JMenuItem mntmColorizeToGreen;
	private JMenuItem mntmAddTransparency;
	
	

	public MainWindow() {
		super();
		initialize();
	}

	public void initialize() {
		this.setSize(1280, 800);
		this.getContentPane().setLayout(null);
		this.setContentPane(retrieveMainPanel());
		this.setTitle("Stamp");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		imageUploader = new ImageUploaderWindow();
	}

	public JPanel retrieveMainPanel() {
		if (pnlMainPanel == null) {
			pnlMainPanel = 	new JPanel();
			pnlMainPanel.setLayout(null);
			pnlMainPanel.add(retrieveScrImagePanel());
			pnlMainPanel.add(retrievePnlStampsPanel());
			pnlMainPanel.add(retrievePnlPreview());
			pnlMainPanel.add(retrieveMenuBar());
			
		}

		return pnlMainPanel;
	}

	private JMenuBar retrieveMenuBar() {
		if (menuBar == null) {
			menuBar = new JMenuBar();
			menuBar.setBounds(0, 0, 1264, 21);
			menuBar.add(retrieveMnFile());
			menuBar.add(retrieveMnEdit());
			menuBar.add(retrieveMnImage());
			
		}
		return menuBar;
	}
	private JMenu retrieveMnFile() {
		if (mnFile == null) {
			mnFile = new JMenu("File");
			mnFile.add(retrieveMntmLoadImage());
			mnFile.add(retrieveMntmSaveImage());
			mnFile.add(retrieveMntmExportAsXml());
			mnFile.add(retrieveMntmExit());
		}
		return mnFile;
	}
	private JMenuItem retrieveMntmLoadImage() {
		if (mntmLoadImage == null) {
			mntmLoadImage = new JMenuItem("Load image");
			mntmLoadImage.setActionCommand("load");
		}
		return mntmLoadImage;
	}
	private JMenuItem retrieveMntmSaveImage() {
		if (mntmSaveImage == null) {
			mntmSaveImage = new JMenuItem("Save image");
			mntmSaveImage.setActionCommand("save");
		}
		return mntmSaveImage;
	}
	private JMenuItem retrieveMntmExit() {
		if (mntmExit == null) {
			mntmExit = new JMenuItem("Exit");
			mntmExit.setActionCommand("exit");
		}
		return mntmExit;
	}
	private JMenu retrieveMnEdit() {
		if (mnEdit == null) {
			mnEdit = new JMenu("Edit");
			mnEdit.add(retrieveMntmResetImage());
		}
		return mnEdit;
	}
	private JMenuItem retrieveMntmResetImage() {
		if (mntmResetImage == null) {
			mntmResetImage = new JMenuItem("Reset Image");
			mntmResetImage.setActionCommand("resetImage");
		}
		return mntmResetImage;
	}
	private JMenuItem retrieveMntmExportAsXml() {
		if (mntmExportAsXml == null) {
			mntmExportAsXml = new JMenuItem("Export as XML");
			mntmExportAsXml.setActionCommand("saveXML");
		}
		return mntmExportAsXml;
	}

	private JMenu retrieveMnImage()
	{
		if(mnImage == null)
		{
			mnImage = new JMenu("Image");
			mnImage.add(retrieveMntmMirrorHorizontally());
			mnImage.add(retrieveMntmMirrorVertically());
			mnImage.add(retrieveMnEffects());
			mnImage.add(retrieveMnRotate());
			mnImage.add(retrieveMntmResize());
			mnImage.setEnabled(false);
		}
		
		return mnImage;
		
	}
	
	private JMenuItem retrieveMntmMirrorHorizontally()
	{
		if(mntmMirrorHorizontally == null)
		{
			mntmMirrorHorizontally = new JMenuItem("Mirror horizontally");
			mntmMirrorHorizontally.setActionCommand("mirrorOnX");
		}
		
		return mntmMirrorHorizontally;
	}
	
	private JMenuItem retrieveMntmMirrorVertically()
	{
		if(mntmMirrorVertically == null)
		{
			mntmMirrorVertically = new JMenuItem("Mirror vertically");
			mntmMirrorVertically.setActionCommand("mirrorOnY");
		}
		
		return mntmMirrorVertically;
	}


	private JMenu retrieveMnRotate()
	{
		if(mnRotate == null)
		{
			mnRotate = new JMenu("Rotate...");
			mnRotate.add(retrieveMntmRotateBy90Clockwise());
			mnRotate.add(retrieveMntmRotateBy90AntiClockwise());
			mnRotate.add(retrieveMntmRotateBy180());
			mnRotate.add(retrieveMntmRotateBy270());
		}
		
		return mnRotate;
	}

	private JMenuItem retrieveMntmRotateBy90Clockwise()
	{
		if(mntmRotateBy90Clockwise == null)
		{
			mntmRotateBy90Clockwise = new JMenuItem("90\u00B0 (Clockwise)");
			mntmRotateBy90Clockwise.setActionCommand("rotateBy90CCW");
		}
		
		return mntmRotateBy90Clockwise;
	}
	
	private JMenuItem retrieveMntmRotateBy90AntiClockwise()
	{
		if (mntmRotateBy90AntiClockwise == null) {
			mntmRotateBy90AntiClockwise = new JMenuItem("90\u00B0 (Anticlockwise)");
			mntmRotateBy90AntiClockwise.setActionCommand("rotateBy90ACW");
		}
		return mntmRotateBy90AntiClockwise;
	}
	
	private JMenuItem retrieveMntmRotateBy180()
	{
		if(mntmRotateBy180 == null)
		{
			mntmRotateBy180 = new JMenuItem("180\u00B0");
			mntmRotateBy180.setActionCommand("rotateBy180");
		}
		
		return mntmRotateBy180;
	}
	
	private JMenuItem retrieveMntmRotateBy270()
	{
		if(mntmRotateBy270 == null)
		{
			mntmRotateBy270 = new JMenuItem("270\u00B0");
			mntmRotateBy270.setActionCommand("rotateBy270");
		}
		
		return mntmRotateBy270;
	}
	
	private JMenu retrieveMnEffects()
	{
		if (mnEffects == null) {
			mnEffects = new JMenu("Effects");
			mnEffects.add(retrieveMntmInvertColors());
			mnEffects.add(retrieveMntmToSepia());
			mnEffects.add(retrieveMntmToGrayScale());
			mnEffects.add(retrieveMntmColorizeToRed());
			mnEffects.add(retrieveMntmColorizeToBlue());
			mnEffects.add(retrieveMntmColorizeToGreen());
			mnEffects.add(retrieveMntmAddTransparency());
		}
		return mnEffects;
	}
	
	private JMenuItem retrieveMntmInvertColors()
	{
		if (mntmInvertColors == null) {
			mntmInvertColors = new JMenuItem("Invert colors");
			mntmInvertColors.setActionCommand("invertColors");
		}
		return mntmInvertColors;
	}
	
	private JMenuItem retrieveMntmToSepia()
	{
		if (mntmToSepia == null) {
			mntmToSepia = new JMenuItem("To sepia");
			mntmToSepia.setActionCommand("toSepia");
		}
		return mntmToSepia;
	}
	
	private JMenuItem retrieveMntmToGrayScale()
	{
		if (mntmToGrayScale == null) {
			mntmToGrayScale = new JMenuItem("To gray scale");
			mntmToGrayScale.setActionCommand("toGrayScale");
		}
		return mntmToGrayScale;
	}
	
	private JMenuItem retrieveMntmColorizeToRed()
	{
		if (mntmColorizeToRed == null) {
			mntmColorizeToRed = new JMenuItem("Colorize to red");
			mntmColorizeToRed.setActionCommand("colorizeToRed");
		}
		return mntmColorizeToRed;
	}
	
	private JMenuItem retrieveMntmColorizeToBlue()
	{
		if (mntmColorizeToBlue == null) {
			mntmColorizeToBlue = new JMenuItem("Colorize to blue");
			mntmColorizeToBlue.setActionCommand("colorizeToBlue");
		}
		return mntmColorizeToBlue;
	}
	
	private JMenuItem retrieveMntmColorizeToGreen()
	{
		if (mntmColorizeToGreen == null) {
			mntmColorizeToGreen = new JMenuItem("Colorize to green");
			mntmColorizeToGreen.setActionCommand("colorizeToGreen");
		}
		return mntmColorizeToGreen;
	}
	
	private JMenuItem retrieveMntmAddTransparency()
	{
		if (mntmAddTransparency == null) {
			mntmAddTransparency = new JMenuItem("Add transparency");
			mntmAddTransparency.setActionCommand("addTransparency");
		}
		return mntmAddTransparency;
	}
	
	private JMenuItem retrieveMntmResize()
	{
		if(mntmResize == null)
		{
			mntmResize = new JMenuItem("Resize...");
			mntmResize.setActionCommand("resize");
		}

		return mntmResize;
	}
	
	private JPanel retrievePnlPreview()
	{
		if(pnlPreview == null)
		{
			pnlPreview = new PreviewPanel();
			pnlPreview.setBorder(new LineBorder(new Color(0, 0, 0), 3));
			pnlPreview.setBounds(902, 158, 300, 300);
			pnlMainPanel.add(pnlPreview);
			pnlPreview.setLayout(new GridBagLayout());
		}
		
		return pnlPreview;
	}

	private JPanel retrievePnlStampsPanel() {
		if (pnlStampsPanel == null) {
			pnlStampsPanel = new StampsPanel();
			pnlStampsPanel.getBtnTopSecret().setLocation(10, 11);
			pnlStampsPanel.getBtnFleurDeLys().setLocation(303, 11);
			pnlStampsPanel.getBtnUsPostage().setLocation(377, 11);
			pnlStampsPanel.getBtnIronMan().setLocation(84, 11);
			pnlStampsPanel.getBtnMailMe().setLocation(232, 11);
			pnlStampsPanel.getBtnSelo().setLocation(158, 11);
			pnlStampsPanel.setBounds(10, 654, 640, 85);
			pnlStampsPanel.setLayout(null);
		}
		return pnlStampsPanel;
	}

	
	public JScrollPane retrieveScrImagePanel() {
		if (scrImagePanel == null) {
			scrImagePanel = new JScrollPane();
			scrImagePanel.setBounds(10, 32, 800, 600);
			scrImagePanel.setViewportBorder(new EtchedBorder(
					EtchedBorder.LOWERED, null, null));
			scrImagePanel.setToolTipText("TESTE");
			scrImagePanel.setViewportView(retrievePnlImagePanel());
		}

		return scrImagePanel;
	}

	public JPanel retrievePnlImagePanel() {
		if (pnlImagePanel == null) {
			GridBagLayout gblPnlImagePanel = new GridBagLayout();
			gblPnlImagePanel.rowWeights = new double[] { 0.0 };
			gblPnlImagePanel.columnWeights = new double[] { 0.0 };
			pnlImagePanel = new JPanel(gblPnlImagePanel);
			pnlImagePanel.setPreferredSize(scrImagePanel.getSize());
			pnlImagePanel.add(retrieveLblBackgroundImageLabel());
		}

		return pnlImagePanel;
	}

	public JLabel retrieveLblBackgroundImageLabel() {
		if (lblBackgroundImageLabel == null) {
			lblBackgroundImageLabel = new BackgroundLabel();
			
			lblBackgroundImageLabel.setLocation(0, 0);
			lblBackgroundImageLabel.setStampImage(new StampBackgroundImage(
					"images/backgrounddefault.png"));
			lblBackgroundImageLabel.load();

			Dimension dim = new Dimension(lblBackgroundImageLabel.getStampImage().getImageIcon().getIconWidth(),
										  lblBackgroundImageLabel.getStampImage().getImageIcon().getIconHeight());
			
			lblBackgroundImageLabel.setPreferredSize(dim);
			System.out.println("Background retrieved.");
		}

		return lblBackgroundImageLabel;
	}

	
	public void configureListener(ActionListener listener) {

		mntmLoadImage.addActionListener(listener);
		mntmResetImage.addActionListener(listener);
		mntmSaveImage.addActionListener(listener);
		mntmExportAsXml.addActionListener(listener);
		
		mntmMirrorHorizontally.addActionListener(listener);
		mntmMirrorVertically.addActionListener(listener);
		mntmRotateBy90Clockwise.addActionListener(listener);
		mntmRotateBy90AntiClockwise.addActionListener(listener);
		mntmRotateBy180.addActionListener(listener);
		mntmRotateBy270.addActionListener(listener);
		mntmResize.addActionListener(listener);
		
		mntmInvertColors.addActionListener(listener);
		mntmToSepia.addActionListener(listener);
		mntmToGrayScale.addActionListener(listener);
		
		mntmColorizeToRed.addActionListener(listener);
		mntmColorizeToGreen.addActionListener(listener);
		mntmColorizeToBlue.addActionListener(listener);
		mntmAddTransparency.addActionListener(listener);
		
		pnlStampsPanel.configureListeners(listener);
	}

	public void configureMouseListener(MouseListener listener) {
		pnlImagePanel.addMouseListener(listener);
	}

	public void changeStampImage(StampImage paramStampImage)
	{ 
		if(paramStampImage != null)
		{
			currentStampImage = paramStampImage;
		}
	}
	
	public StampImage getCurrentStampImage() {
		return currentStampImage;
	}

	public void setCurrentStampImage(StampImage currentStampImage) {
		this.currentStampImage = currentStampImage;
	}

	public BackgroundLabel getLblBackgroundImageLabel() {
		return lblBackgroundImageLabel;
	}

	public void setLblBackgroundImageLabel(BackgroundLabel lblBackgroundImageLabel) {
		this.lblBackgroundImageLabel = lblBackgroundImageLabel;
	}

	public ImageUploaderWindow getImageUploader() {
		return imageUploader;
	}

	public void setImageUploader(ImageUploaderWindow imageUploader) {
		this.imageUploader = imageUploader;
	}

	public StampsPanel getPnlStampsPanel() {
		return pnlStampsPanel;
	}

	public void setPnlStampsPanel(StampsPanel pnlStampsPanel) {
		this.pnlStampsPanel = pnlStampsPanel;
	}

	public PreviewPanel getPnlPreview() {
		return pnlPreview;
	}

	public void setPnlPreview(PreviewPanel pnlPreview) {
		this.pnlPreview = pnlPreview;
	}

	public JMenu getMnImage() {
		return mnImage;
	}

	public void setMnImage(JMenu mnImage) {
		this.mnImage = mnImage;
	}

	public JScrollPane getScrImagePanel() {
		return scrImagePanel;
	}

	public void setScrImagePanel(JScrollPane scrImagePanel) {
		this.scrImagePanel = scrImagePanel;
	}

	public JPanel getPnlImagePanel() {
		return pnlImagePanel;
	}

	public void setPnlImagePanel(JPanel pnlImagePanel) {
		this.pnlImagePanel = pnlImagePanel;
	}
	

}
